#include "VGPLib.h"
#include "Engine.h"

VGPLib* VGPLib::vgplib;

VGPLib::VGPLib()
{		
	vgplib = NULL;
}

VGPLib::~VGPLib()
{
}

VGPLib* VGPLib::GetVGPLib()
{
	if ( vgplib == NULL )
		vgplib = new VGPLib();
	return vgplib;
}

void VGPLib::StartGraphics2D()
{
	glDisable(GL_CULL_FACE);
	glDisable(GL_DEPTH_TEST);
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}

void VGPLib::EndGraphics2D()
{
	glDisable(GL_BLEND);
	glEnable(GL_DEPTH_TEST);	
	glEnable(GL_CULL_FACE);
}

//draw image with: (x, y, w, h) on screen at (tx, ty, tw, th) and with flag 

void VGPLib::PaintImage(int x, int y, int w, int h, int sx, int sy, int sw, int sh, int flag, GLuint textureID, int widthImage, int heightImage)
{
	StartGraphics2D();	
	
	float v_vertices[] = { sx, sy, (sx + sw), sy, (sx + sw), (sy + sh), sx, (sy + sh) };
	float v_uv_0 = x/(1.0*widthImage);
	float v_uv_1 = y/(1.0*heightImage);
	float v_uv_2 = (x + w)/(1.0*widthImage);
	float v_uv_3 = y/(1.0*heightImage);
	float v_uv_4 = (x + w)/(1.0*widthImage);
	float v_uv_5 = (y + h)/(1.0*heightImage);
	float v_uv_6 = x/(1.0*widthImage);
	float v_uv_7 = (y + h)/(1.0*heightImage);
	float v_uv[]= { v_uv_0, v_uv_1, v_uv_2, v_uv_3, v_uv_4, v_uv_5, v_uv_6, v_uv_7 };

	if ( flag == FREE_ROT )
	{			
	}
	else if ( flag == FLIP_X )
	{		
		v_uv[0] = v_uv_2;
		v_uv[1] = v_uv_3;
		v_uv[2] = v_uv_0;
		v_uv[3] = v_uv_1;
		v_uv[4] = v_uv_6;
		v_uv[5] = v_uv_7;
		v_uv[6] = v_uv_4;
		v_uv[7] = v_uv_5;
	}
	else if ( flag == FLIP_Y )
	{
		v_uv[0] = v_uv_6;
		v_uv[1] = v_uv_7;
		v_uv[2] = v_uv_4;
		v_uv[3] = v_uv_5;
		v_uv[4] = v_uv_2;
		v_uv[5] = v_uv_3;
		v_uv[6] = v_uv_0;
		v_uv[7] = v_uv_1;
	}
	else if ( flag == ROT_90 )
	{
		v_vertices[0] = sx;
		v_vertices[1] = sy;
		v_vertices[2] = sx + sh;
		v_vertices[3] = sy;
		v_vertices[4] = sx + sh;
		v_vertices[5] = sy + sw;
		v_vertices[6] = sx;
		v_vertices[7] = sy + sw;
		v_uv[0] = v_uv_6;
		v_uv[1] = v_uv_7;
		v_uv[2] = v_uv_0;
		v_uv[3] = v_uv_1;
		v_uv[4] = v_uv_2;
		v_uv[5] = v_uv_3;
		v_uv[6] = v_uv_4;
		v_uv[7] = v_uv_5;
	}
	else if ( flag ==  ( FLIP_X | FLIP_Y ) )
	{
		v_uv[0] = v_uv_4;
		v_uv[1] = v_uv_5;
		v_uv[2] = v_uv_6;
		v_uv[3] = v_uv_7;
		v_uv[4] = v_uv_0;
		v_uv[5] = v_uv_1;
		v_uv[6] = v_uv_2;
		v_uv[7] = v_uv_3;
	}	
	else if ( flag ==  ( FLIP_X | ROT_90 ) )
	{
		v_vertices[0] = sx;
		v_vertices[1] = sy;
		v_vertices[2] = sx + sh;
		v_vertices[3] = sy;
		v_vertices[4] = sx + sh;
		v_vertices[5] = sy + sw;
		v_vertices[6] = sx;
		v_vertices[7] = sy + sw;
		v_uv[0] = v_uv_4;
		v_uv[1] = v_uv_5;
		v_uv[2] = v_uv_2;
		v_uv[3] = v_uv_3;
		v_uv[4] = v_uv_0;
		v_uv[5] = v_uv_1;
		v_uv[6] = v_uv_6;
		v_uv[7] = v_uv_5;
	}
	else if ( flag ==  ( FLIP_Y | ROT_90 ) )
	{
		v_vertices[0] = sx;
		v_vertices[1] = sy;
		v_vertices[2] = sx + sh;
		v_vertices[3] = sy;
		v_vertices[4] = sx + sh;
		v_vertices[5] = sy + sw;
		v_vertices[6] = sx;
		v_vertices[7] = sy + sw;
		v_uv[0] = v_uv_0;
		v_uv[1] = v_uv_1;
		v_uv[2] = v_uv_6;
		v_uv[3] = v_uv_7;
		v_uv[4] = v_uv_4;
		v_uv[5] = v_uv_5;
		v_uv[6] = v_uv_2;
		v_uv[7] = v_uv_3;
	}
	else //FLIP_X | FLIP_Y | ROT_90
	{
		v_vertices[0] = sx;
		v_vertices[1] = sy;
		v_vertices[2] = sx + sh;
		v_vertices[3] = sy;
		v_vertices[4] = sx + sh;
		v_vertices[5] = sy + sw;
		v_vertices[6] = sx;
		v_vertices[7] = sy + sw;
		v_uv[0] = v_uv_2;
		v_uv[1] = v_uv_3;
		v_uv[2] = v_uv_4;
		v_uv[3] = v_uv_5;
		v_uv[4] = v_uv_6;
		v_uv[5] = v_uv_7;
		v_uv[6] = v_uv_0;
		v_uv[7] = v_uv_1;
	}

	Matrix matrixsform;
	matrixsform.LoadOrthoGraphics(0, SCREEN_W, SCREEN_H, 0, 1, -1);

	Graphics::GetGraphics()->SetProgram(Uniforms::program);
	glUniformMatrix4fv(Uniforms::uWvpMatrix, 1, GL_FALSE, matrixsform.value);
	glVertexAttribPointer(ATTRIB_POSITION, 2,  GL_FLOAT, GL_FALSE, 0, v_vertices);
	glEnableVertexAttribArray(ATTRIB_POSITION);

	glVertexAttribPointer(ATTRIB_TEXCOORD, 2, GL_FLOAT, GL_FALSE,0, v_uv);
	glEnableVertexAttribArray(ATTRIB_TEXCOORD);

	glBindTexture(GL_TEXTURE_2D, textureID);
	glActiveTexture(GL_TEXTURE0);

	glDrawArrays(GL_TRIANGLE_FAN,0, 4);   
	
	EndGraphics2D();
}	

void VGPLib::PaintRectangle(int x, int y, int w, int h, int flag)
{
	//StartGraphics2D();	//Draw last , So no need (after draw menu)
	if (flag == ( VGPLib::TOP | VGPLib::RIGHT ) )
	{
		x = x - w;
	}
	else if (flag == (  VGPLib::TOP | VGPLib::CENTER ) )
	{
		x = x - w/2;
	}
	else if (flag == (  VGPLib::LEFT | VGPLib::BOTTOM ) )
	{
		y = y - h;
	}
	else if (flag == (  VGPLib::RIGHT | VGPLib::BOTTOM ) )
	{
		x = x - w;
		y = y - h;
	}
	else if (flag == (  VGPLib::CENTER | VGPLib::BOTTOM ) )
	{
		x = x - w/2;
		y = y - h;
	}
	else if (flag == (  VGPLib::CENTER | VGPLib::CENTER ) )
	{
		x = x - w/2;
		y = y - h/2;
	}
	float v_vertices[] = { (x + w), (y + h), x, (y + h), x, y, (x + w), y};	
	
	Graphics::GetGraphics()->SetProgram(Uniforms::program);
	glVertexAttribPointer(ATTRIB_POSITION, 2,  GL_FLOAT, GL_FALSE, 0, v_vertices);
	glEnableVertexAttribArray(ATTRIB_POSITION);	
	
	glDrawArrays(GL_LINE_LOOP,0, 4);   	
	//EndGraphics2D();		//Draw last , So no need (after draw menu)
}	

void VGPLib::PaintRectangle(int x, int y, int w, int h)
{
	PaintRectangle(x, y, w, h, VGPLib::TOP | VGPLib::LEFT);
}

char* VGPLib::ConvertNumberToString ( int a )
{
	int _array[100];
	int n = a, count = 0;
	while ( n != 0 )
	{
		_array[count] = n % 10;
		n /= 10;
		count ++;
	}
	
	char* str = new char[ count + 1 ];
	for ( int i = count - 1; i  >= 0; i-- )
		str[count - i - 1] = _array[i] + '0';

	str[count] = '\0';

	return str;
}

